package com.starhub.utils;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import lombok.extern.slf4j.Slf4j;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;

/**   
 * 对象转换工具类
 * @version: V1.0
 * @author: liuhf
 * @time 2025-05-21
 */
@Slf4j
public class HubBeanUtils {

    /**
     * 对象属性复制，支持类型转换
     * @param source 源对象
     * @param target 目标对象
     * @param <S> 源对象类型
     * @param <T> 目标对象类型
     * @return 转换后的目标对象
     */
    public static <S, T> T convert(S source, Class<T> targetClass) {
        if (source == null) {
            return null;
        }
        try {
            T target = targetClass.getDeclaredConstructor().newInstance();
            copyProperties(source, target);
            return target;
        } catch (Exception e) {
            log.error("对象转换失败: {}", e.getMessage());
            throw new RuntimeException("对象转换失败", e);
        }
    }

    /**
     * 对象属性复制，支持类型转换
     * @param source 源对象
     * @param target 目标对象
     * @param <S> 源对象类型
     * @param <T> 目标对象类型
     */
    public static <S, T> void copyProperties(S source, T target) {
        if (source == null || target == null) {
            return;
        }

        BeanWrapper sourceWrapper = new BeanWrapperImpl(source);
        BeanWrapper targetWrapper = new BeanWrapperImpl(target);

        PropertyDescriptor[] sourceDescriptors = sourceWrapper.getPropertyDescriptors();
        for (PropertyDescriptor sourceDescriptor : sourceDescriptors) {
            String propertyName = sourceDescriptor.getName();
            
            // 跳过class属性
            if ("class".equals(propertyName)) {
                continue;
            }

            // 获取源对象属性值
            Object sourceValue = sourceWrapper.getPropertyValue(propertyName);
            if (sourceValue == null) {
                continue;
            }

            // 检查目标对象是否存在该属性
            if (!targetWrapper.isWritableProperty(propertyName)) {
                continue;
            }

            // 获取目标对象属性类型
            PropertyDescriptor targetDescriptor = targetWrapper.getPropertyDescriptor(propertyName);
            if (targetDescriptor == null) {
                continue;
            }

            // 类型转换处理
            Object convertedValue = convertValue(sourceValue, targetDescriptor.getPropertyType());
            if (convertedValue != null) {
                targetWrapper.setPropertyValue(propertyName, convertedValue);
            }
        }
    }

    /**
     * 值类型转换
     * @param value 源值
     * @param targetType 目标类型
     * @return 转换后的值
     */
    private static Object convertValue(Object value, Class<?> targetType) {
        if (value == null) {
            return null;
        }

        // 如果类型相同，直接返回
        if (targetType.isInstance(value)) {
            return value;
        }

        // Long 转 String
        if (value instanceof Long && targetType == String.class) {
            return Util.null2String(value);
        }

        // String 转 Long
        if (value instanceof String && targetType == Long.class) {
            try {
                return Util.getLongValue(Util.null2String(value));
            } catch (NumberFormatException e) {
                return null;
            }
        }

        // 其他类型转换可以在这里添加
        return null;
    }

    /**
     * 批量对象转换
     * @param sourceList 源对象列表
     * @param targetClass 目标对象类型
     * @param <S> 源对象类型
     * @param <T> 目标对象类型
     * @return 转换后的目标对象列表
     */
    public static <S, T> List<T> convertList(List<S> sourceList, Class<T> targetClass) {
        if (sourceList == null) {
            return new ArrayList<>();
        }
        List<T> targetList = new ArrayList<>(sourceList.size());
        for (S source : sourceList) {
            targetList.add(convert(source, targetClass));
        }
        return targetList;
    }
}
